package com.betameta.rotativobh.base;

import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.model.LatLng;

public class LocationBase extends Activity implements 
		GooglePlayServicesClient.ConnectionCallbacks,
		GooglePlayServicesClient.OnConnectionFailedListener,
		LocationListener {
	// Milliseconds per second
    private static final int MILLISECONDS_PER_SECOND = 1000;
    // Update frequency in seconds
    public static final int UPDATE_INTERVAL_IN_SECONDS = 3;
    // Update frequency in milliseconds
    private static final long UPDATE_INTERVAL =
            MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
    // The fastest update frequency, in seconds
    private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
    // A fast frequency ceiling in milliseconds
    private static final long FASTEST_INTERVAL =
            MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
	private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
	private LocationClient mLocationClient;
	private Location mCurrentLocation;
	private LocationRequest mLocationRequest;
	private boolean connected;
	private boolean mUpdatesRequested;
	SharedPreferences mPrefs;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mLocationClient = new LocationClient(this, this, this);
		mLocationRequest = LocationRequest.create();
		mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
		mLocationRequest.setInterval(UPDATE_INTERVAL);
		mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
		
		mPrefs = getSharedPreferences("SharedPreferences", 
				Context.MODE_PRIVATE);
	}

	@Override
	protected void onStart() {
		super.onStart();
		mLocationClient.connect();
	}

	@Override
	protected void onStop() {
		// If the client is connected
        if (mLocationClient.isConnected()) {
            /*
             * Remove location updates for a listener.
             * The current Activity is the listener, so
             * the argument is "this".
             */
            mLocationClient.removeLocationUpdates(this);
        }
		mLocationClient.disconnect();
		super.onStop();
	}

	public static class ErrorDialogFragment extends DialogFragment {
	// Global field to contain the error dialog
		private Dialog mDialog;
		// Default constructor. Sets the dialog field to null
		public ErrorDialogFragment() {
		    super();
		    mDialog = null;
		}
		// Set the dialog to display
		public void setDialog(Dialog dialog) {
		    mDialog = dialog;
		}
		// Return a Dialog to the DialogFragment.
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
		    return mDialog;
		}
	}
	
	@Override
    protected void onPause() {
        // Save the current setting for updates
        mPrefs.edit().putBoolean("KEY_UPDATES_ON", mUpdatesRequested);
        mPrefs.edit().commit();
        super.onPause();
    }
	
	@Override
    protected void onResume() {
		super.onResume();
        /*
         * Get any previous setting for location updates
         * Gets "false" if an error occurs
         */
        if (mPrefs.contains("KEY_UPDATES_ON")) {
            mUpdatesRequested =
                    mPrefs.getBoolean("KEY_UPDATES_ON", false);

        // Otherwise, turn off location updates
        } else {
            mPrefs.edit().putBoolean("KEY_UPDATES_ON", false);
            mPrefs.edit().commit();
        }
    }

	@Override
	protected void onActivityResult(
	    int requestCode, int resultCode, Intent data) {
		// Decide what to do based on the original request code
		switch (requestCode) {
		    case CONNECTION_FAILURE_RESOLUTION_REQUEST :
		    /*
		     * If the result code is Activity.RESULT_OK, try
		     * to connect again
		     */
		        switch (resultCode) {
		            case Activity.RESULT_OK :
		            /*
		             * Try the request again
		             */
		            break;
		        }
		}
	}

	private boolean servicesConnected() {
		// Check that Google Play services is available
		int resultCode =
		        GooglePlayServicesUtil.
		                isGooglePlayServicesAvailable(this);
		// If Google Play services is available
		if (ConnectionResult.SUCCESS == resultCode) {
		    // In debug mode, log the status
		    Log.d("Location Updates",
		            "Google Play services is available.");
		    // Continue
		    return true;
		// Google Play services was not available for some reason
		} else {
		    // Get the error code
			ConnectionResult cr = new ConnectionResult(resultCode, null);
		    int errorCode = cr.getErrorCode();
		    // Get the error dialog from Google Play services
		    Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
		            errorCode,
		            this,
		            CONNECTION_FAILURE_RESOLUTION_REQUEST);
		
		    // If Google Play services can provide an error dialog
		    if (errorDialog != null) {
		        // Create a new DialogFragment for the error dialog
		        ErrorDialogFragment errorFragment =
		                new ErrorDialogFragment();
		        // Set the dialog in the DialogFragment
		        errorFragment.setDialog(errorDialog);
		        // Show the error dialog in the DialogFragment
		        errorFragment.show(getFragmentManager(), LOCATION_SERVICE);
		    }
		    return false;
		}
	}

	@Override
	public void onConnected(Bundle dataBundle) {
		connected = true;
		// Display the connection status
		Toast.makeText(this, "Conectado", Toast.LENGTH_SHORT).show();
		mLocationClient.requestLocationUpdates(mLocationRequest, this);
	}

	@Override
	public void onDisconnected() {
		connected = false;
		// Display the connection status
		Toast.makeText(this, "Desconectado. Por favor, reconecte-se.",
		        Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onConnectionFailed(ConnectionResult connectionResult) {
		/*
		 * Google Play services can resolve some errors it detects.
		 * If the error has a resolution, try sending an Intent to
		 * start a Google Play services activity that can resolve
		 * error.
		 */
		if (connectionResult.hasResolution()) {
		    try {
		        // Start an Activity that tries to resolve the error
		        connectionResult.startResolutionForResult(
		                this,
		                CONNECTION_FAILURE_RESOLUTION_REQUEST);
		        /*
		         * Thrown if Google Play services canceled the original
		         * PendingIntent
		         */
		    } catch (IntentSender.SendIntentException e) {
		        // Log the error
		        e.printStackTrace();
		    }
		} else {
		    /*
		     * If no resolution is available, display a dialog to the
		     * user with the error.
		     */
		    //showErrorDialog(connectionResult.getErrorCode());
		}
	}
	
	@Override
    public void onLocationChanged(Location location) {
        // Report to the UI that the location was updated
        /*String msg = "Updated Location: " +
                Double.toString(location.getLatitude()) + "," +
                Double.toString(location.getLongitude());
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();*/
    }

	public LatLng getCurrentPosition() {
		if (connected && servicesConnected()) {
			mCurrentLocation = mLocationClient.getLastLocation();
			Toast.makeText(this, "Altitude: " + mCurrentLocation.getLatitude() +
			"Latitude: " + mCurrentLocation.getLongitude(), Toast.LENGTH_LONG).show();
			return new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
		}
		return null;
	}
}